package com.lemon.smartsafetynew.ui.activity.monitor;

import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.lemon.android.http.LemonRequestParams;
import com.lemon.smartsafety.R;
import com.lemon.smartsafety.app.AppManager;
import com.lemon.smartsafety.app.Constants;
import com.lemon.smartsafety.entity.event.http.HttpCallbackEvent;
import com.lemon.smartsafety.http.callback.HandlerCallback;
import com.lemon.smartsafetynew.ui.activity.base.BaseActivity;
import com.lemon.smartsafety.utils.app.HUDUtil;
import com.lemon.smartsafetynew.entity.monitor.MonitorDetailItemVo;
import com.lemon.smartsafetynew.entity.monitor.MonitorItemVo;
import com.lemon.smartsafetynew.entity.monitor.MonitorSensorData;
import com.lemon.smartsafetynew.entity.monitor.MonitorSensorResult;
import com.lemon.smartsafetynew.net.services.MonitorServices;
import com.lemon.smartsafetynew.ui.widget.SortView;
import com.lemon.smartsafetynew.ui.widget.marker.MyMarkerView;
import com.lemon.smartsafetynew.util.common.ColorUtil;
import com.lemon.smartsafetynew.util.common.CommonUtil;
import com.lemon.smartsafetynew.util.constants.KeyConstants;
import com.lemon.smartsafetynew.util.constants.TimeFormatConstants;
import com.zhy.http.okhttp.OkHttpUtils;

import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import butterknife.Bind;

/**
 * Created by Andrew on 2017/8/9.
 */

public class MonitorSensorActivity extends BaseActivity {

    @Bind(R.id.monitor_item_name)
    TextView monitorItemName;
    @Bind(R.id.title_layout)
    LinearLayout titleLayout;
    @Bind(R.id.sensor_name_tv)
    TextView sensorNameTv;
    @Bind(R.id.now_value)
    TextView nowValue;
    @Bind(R.id.now_layout)
    LinearLayout nowLayout;
    @Bind(R.id.max_value)
    TextView maxValue;
    @Bind(R.id.max_layout)
    LinearLayout maxLayout;
    @Bind(R.id.min_value)
    TextView minValue;
    @Bind(R.id.min_layout)
    LinearLayout minLayout;
    @Bind(R.id.avg_value)
    TextView avgValue;
    @Bind(R.id.avg_layout)
    LinearLayout avgLayout;
    @Bind(R.id.normal_value)
    TextView normalValue;
    @Bind(R.id.abnormal_value)
    TextView abnormalValue;
    @Bind(R.id.line_chart)
    LineChart lineChart;
    @Bind(R.id.chart_layout)
    LinearLayout chartLayout;
    @Bind(R.id.sensor_value_sort_tv)
    TextView sensorValueSortTv;
    @Bind(R.id.ball_layout)
    LinearLayout ballLayout;
    //@Bind(R.id.sort_view)
    //MonitorSortView sortView;
    @Bind(R.id.main_title)
    TextView mainTitle;
    @Bind(R.id.toolbar)
    Toolbar toolbar;

    SortView sortView;

    private static MonitorDetailItemVo detailItemVo;
    private static MonitorItemVo itemVo;

    private Timer timer;

    @Override
    protected void getBundleArgs() {

        Bundle bundle = getIntent().getExtras();
        if (bundle != null) {
            detailItemVo = (MonitorDetailItemVo) bundle.getSerializable(KeyConstants.KEY_MONITOR_SENSOR_INFO);
            itemVo = (MonitorItemVo) bundle.getSerializable(KeyConstants.KEY_MONITOR_ITEM_VO);
        } else {
            callFinish();
        }
    }


    @Override
    protected int getContentViewId() {
        return R.layout.activity_monitor_sensor;
    }

    @Override
    protected void initViews() {

        sortView = (SortView) findViewById(R.id.sort_view);

        initToolbar();
        initLabelBar();
        initLineChart();

        //sortView.setFlag(true);
    }

    @Override
    protected void onResume() {
        super.onResume();
        startGetNetData();
    }

    private void initToolbar() {

        toolbar.setTitle("");
        mainTitle.setText(detailItemVo.getName());
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                callFinish();
            }
        });

    }

    private void initLabelBar() {
        monitorItemName.setText(itemVo.getName());
        sensorNameTv.setText(detailItemVo.getName() + "实时趋势图");
        sensorValueSortTv.setText(detailItemVo.getName() + "（出现次数前5）");
    }

    private void initLineChartLabel(MonitorSensorResult sensorResult) {

        if (sensorResult.getSenseDatalist() == null && sensorResult.getSenseDatalist().size() == 0) {
            return;
        }

        int size = sensorResult.getSenseDatalist().size();

        nowValue.setText(CommonUtil.formatData(sensorResult.getSenseDatalist().get(size - 1).getValue()));
        maxValue.setText(CommonUtil.formatData(sensorResult.getMax()));
        minValue.setText(CommonUtil.formatData(sensorResult.getMin()));
        avgValue.setText(CommonUtil.formatData(sensorResult.getAvg()));
    }

    private void initSortView(List<MonitorSensorData> sensorDatas) {

        HashMap<String, Integer> hashMap = new HashMap<String, Integer>();
        for (MonitorSensorData sensorData : sensorDatas) {
            if (hashMap.get(sensorData.getValue()) != null) {
                Integer value = hashMap.get(sensorData.getValue());
                hashMap.put(sensorData.getValue(), value + 1);
            } else {
                hashMap.put(sensorData.getValue(), 1);
            }
        }

        List<Map.Entry<String, Integer>> infoIds =
                new ArrayList<Map.Entry<String, Integer>>(hashMap.entrySet());

        //排序
        Collections.sort(infoIds, new Comparator<Map.Entry<String, Integer>>() {
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return (o2.getValue() - o1.getValue());
                //return (o1.getKey()).toString().compareTo(o2.getKey());
            }
        });

        List<SortView.CircleDataVo> list = new ArrayList<>();

        for (int i = 0; i < Math.min(infoIds.size(), 5); i++) {
            list.add(new SortView.CircleDataVo("", infoIds.get(i).getKey(), infoIds.get(i).getValue() + "次"));
        }

        sortView.setDataList(list);

    }

    private void callFinish() {
        AppManager.getAppManager().finishActivity(MonitorSensorActivity.this);
    }

    private void getSensorData() {

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        LemonRequestParams params = new LemonRequestParams("");
        params.put("topic", itemVo.getPlaceId());
        params.put("time", CommonUtil.timeToStr(calendar.getTime()));
        params.put("id", detailItemVo.getId());

        MonitorServices.init().getSensorRealTimeData(params);

    }


    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onMainThread(HttpCallbackEvent event) {

        if (KeyConstants.URL_GET_MONITOR_SENSOR_REAL_TIME.equals(event.getTag())) {
            if (HandlerCallback.HttpFlow.START == event.getHttpFlow()) {
                mHUDUtil.showHUD();
            } else if (HandlerCallback.HttpFlow.FINISH == event.getHttpFlow()) {
                mHUDUtil.hidden();

                if (Constants.Result.SUCCESS == event.getEventResult()) {

                    MonitorSensorResult sensorResult = (MonitorSensorResult) event.getObj();

                    initLineChartLabel(sensorResult);
                    showChartHour(sensorResult.getSenseDatalist());
                    initSortView(sensorResult.getSenseDatalist());

                } else if (Constants.Result.ERROR == event.getEventResult()) {

                    mHUDUtil.showErrorTip(event.getMsg(), new HUDUtil.CallBack() {
                        @Override
                        public void onCall() {
                            callFinish();
                        }
                    });
                }
            }
        }

    }

    // ======== LineChart ========
    private void initLineChart() {

        lineChart.setDrawGridBackground(false);
        lineChart.setNoDataText("无数据");
        // no description text
        lineChart.getDescription().setEnabled(false);

        // enable touch gestures
        lineChart.setTouchEnabled(true);

        // enable scaling and dragging
        lineChart.setDragEnabled(true);
        lineChart.setScaleEnabled(false);
        lineChart.setScaleXEnabled(true);
        lineChart.setDoubleTapToZoomEnabled(false);
        // mChart.setScaleYEnabled(true);

        // if disabled, scaling can be done on x- and y-axis separately
        lineChart.setPinchZoom(false);

        lineChart.fitScreen();

        // set an alternative background color
        // mChart.setBackgroundColor(Color.GRAY);

        // create a custom MarkerView (extend MarkerView) and specify the layout
        // to use for it
        MyMarkerView mv = new MyMarkerView(MonitorSensorActivity.this, R.layout.custom_marker_view);
        mv.setChartView(lineChart); // For bounds control
        lineChart.setMarker(mv); // Set the marker to the chart

        YAxis leftAxis = lineChart.getAxisLeft();
        leftAxis.removeAllLimitLines(); // reset all limit lines to avoid overlapping lines
        //leftAxis.setAxisMinimum(0f);  //适配data value
        leftAxis.setDrawZeroLine(false);
        leftAxis.setDrawGridLines(false);

        // limit lines are drawn behind data (and not on top)
        //leftAxis.setDrawLimitLinesBehindData(true);
        lineChart.getAxisRight().setEnabled(false);

        // add data
        //setLineChartData(24, 1000);

        //lineChart.setVisibleXRangeMaximum(6.2f);
        //lineChart.setVisibleXRangeMinimum(0);
        //lineChart.animateX(500);
        //mChart.invalidate();

        // get the legend (only possible after setting data)
        Legend l = lineChart.getLegend();
        l.setEnabled(false);

        // // dont forget to refresh the drawing
        lineChart.invalidate();

    }

    private void showChartHour(List<MonitorSensorData> list) {

        if (list == null || list.size() == 0) {
            return;
        }

        List<String> strings = new ArrayList<>();

        for (MonitorSensorData sensorData : list) {
            strings.add(sensorData.getTime());
        }

        ArrayList<Entry> values = new ArrayList<>();

        for (int i = 0; i < list.size(); i++) {
            values.add(new Entry(i, Float.valueOf(list.get(i).getValue())));
        }

        LineDataSet set1;

        set1 = new LineDataSet(values, "DataSet 1");
        set1.setDrawValues(false);

        // set the line to be drawn like this "- - - - - -"
        set1.enableDashedLine(10f, 5f, 0f);
        set1.enableDashedHighlightLine(10f, 5f, 0f);
        set1.setColor(Color.parseColor(ColorUtil.lineChartColor));
        set1.setCircleColor(Color.parseColor(ColorUtil.lineChartColor));
        set1.setLineWidth(1f);
        set1.setCircleRadius(3f);
        set1.setDrawCircleHole(false);
        set1.setValueTextSize(9f);
        set1.setDrawFilled(true);
        set1.setFormLineWidth(1f);
        set1.setFormLineDashEffect(new DashPathEffect(new float[]{10f, 5f}, 0f));
        set1.setFormSize(15.f);
        set1.setHighLightColor(Color.TRANSPARENT);

        set1.setFillColor(Color.parseColor(ColorUtil.lineChartColor));

        ArrayList<ILineDataSet> dataSets = new ArrayList<>();
        dataSets.add(set1); // add the datasets

        // create a data object with the datasets
        LineData data = new LineData(dataSets);

        // set data
        lineChart.setData(data);

        XAxis xAxis = lineChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setAxisMinimum(0f);
        xAxis.setValueFormatter(new TimeIAxisValueFormatter(strings));
        xAxis.setAvoidFirstLastClipping(true);
        xAxis.setGranularity(1f);

        lineChart.setVisibleXRangeMaximum(4.2f);

        lineChart.moveViewToX(list.size());

        lineChart.invalidate();
    }

    private class TimeIAxisValueFormatter implements IAxisValueFormatter {

        List<String> timeStrList = new ArrayList<>();

        public TimeIAxisValueFormatter(List<String> strings) {
            timeStrList = strings;
        }

        @Override
        public String getFormattedValue(float value, AxisBase axis) {

            int val = (int) value;
            if(val >= timeStrList.size() || val < 0) {
                return "";
            } else {
                String timeStamp = timeStrList.get((int) value);
                Date date = CommonUtil.timeStrToDate(timeStamp, TimeFormatConstants.FORMAT_TIME);
                return CommonUtil.timeToStr(date, TimeFormatConstants.FORMAT_TIME3);
            }
        }
    }

    /**
     * 按频率获取一次数据
     */
    private final static int TIMES = 5; //5s一次
    private void startGetNetData() {

        timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                getSensorData();
            }
        }, 0, 1000 * TIMES);
    }

    /**
     * 清理对象，缓存等
     */
    private void clear() {

        if (timer != null) {
            timer.cancel();
            timer.purge();
            timer = null;
        }
        OkHttpUtils.getInstance().cancelTag(KeyConstants.URL_GET_MONITOR_SENSOR_REAL_TIME);
    }

    @Override
    protected void onPause() {
        super.onPause();
        clear();
    }

}
